package com.example.sfzreader.core;

import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import com.example.mt3yreader.NativeFunc;
import com.example.sfzreader.contact.Contacts;
import com.example.sfzreader.utils.RootCmd;
import com.example.sfzreader.utils.SerialPortFinder;
import com.example.sfzreader.utils.ThreadUtils;
import com.example.sfzreader.utils.UsbDevPermission;

import java.util.HashSet;
import java.util.Set;

public class IDCardReaderManager {
    private String defaultSerialPath = "/dev/ttyS1";
    private Set<String> chmodCmdString = new HashSet<String>();
    private SerialPortFinder serialPortFinder = new SerialPortFinder();
    private int deviceType;
    private UsbDevPermission usbPermission;
    private ThreadUtils.Task<Void> mInitTask;

    public IDCardReaderManager() {
    }

    private static class Holder {
        static IDCardReaderManager INSTANCE = new IDCardReaderManager();
    }

    public static IDCardReaderManager getInstance() {
        return Holder.INSTANCE;
    }

    public IDCardReaderManager setDeviceType(int deviceType) {
        this.deviceType = deviceType;
        return this;
    }

    public void init(IReadInitCallback callback) {
        initTask(callback);
        ThreadUtils.executeByFixed(1, mInitTask);
    }

    private void initTask(IReadInitCallback callback) {
        if (mInitTask == null) {
            mInitTask = new ThreadUtils.Task<Void>() {
                @Override
                public Void doInBackground() {
                    openIdReader(callback);
                    return null;
                }

                @Override
                public void onSuccess(Void result) {

                }

                @Override
                public void onCancel() {
                }

                @Override
                public void onFail(Throwable t) {
                    if (callback != null) {
                        callback.onCallback(t.getMessage());
                    }
                }
            };
        }
    }

    private void closeIdReader() {
        int ret = NativeFunc.mt8deviceclose();
//        ReaderResultBean readerResultBean = new ReaderResultBean();
        if (ret == 0) {
            Looper.prepare();
            Toast.makeText(IDCardReaderClientHelper.getApplicationByReflect(), "[身份证读卡器]关闭设备成功" + ret, Toast.LENGTH_SHORT).show();
            Looper.loop();
        } else {
            Looper.prepare();
            Toast.makeText(IDCardReaderClientHelper.getApplicationByReflect(), "[身份证读卡器]关闭设备失败" + ret, Toast.LENGTH_SHORT).show();
            Looper.loop();
        }
        unReigsterUsbPermission();
    }

    private void openIdReader(IReadInitCallback callback) {
        if (usbPermission==null){
            usbPermission = new UsbDevPermission(IDCardReaderClientHelper.getApplicationByReflect());
        }
        String[] serials = null;
        try {
            serials = serialPortFinder.getAllDevicesPath();
        } catch (Throwable ex) {
            ex.printStackTrace();
            // showMessage(ex.toString(),0);
        }
        if (serials != null) {
            for (String serial : serials) {
                String chmodSerial = "chmod 777 " + serial + ";";
                chmodCmdString.add(chmodSerial);
            }
            RootCmd.chmodShell(chmodCmdString);
        } else {
            serials = new String[1];
            serials[0] = defaultSerialPath;
        }
        RootCmd.chmodShell(chmodCmdString);
        initCmdList();
        if (Contacts.USB_MODE == deviceType) {
            openUsbDevice(callback);
        }
    }

    private void initCmdList() {
        chmodCmdString.add("chmod 777 /dev/;");
        chmodCmdString.add("chmod 777 /dev/bus/;");
        chmodCmdString.add("chmod 777 /dev/bus/usb/;");
        chmodCmdString.add("chmod 777 /dev/bus/usb/0*;");
        chmodCmdString.add("chmod 777 /dev/bus/usb/001/*;");
        chmodCmdString.add("chmod 777 /dev/bus/usb/002/*;");
        chmodCmdString.add("chmod 777 /dev/bus/usb/003/*;");
        chmodCmdString.add("chmod 777 /dev/bus/usb/004/*;");
        chmodCmdString.add("chmod 777 /dev/bus/usb/005/*;");
    }

    private void openUsbDevice(IReadInitCallback initCallback) {
//        ReaderResultBean readerResultBean = new ReaderResultBean();

        int m_device_fd = usbPermission.getUsbFileDescriptor(0x23A4, 0x0219);
        if (m_device_fd < 0) {
            m_device_fd = usbPermission.getUsbFileDescriptor(0x23A4, 0x0219);
            if (m_device_fd < 0) {
                if (initCallback != null) {
                    initCallback.onCallback("[身份证读卡器]获取USB设备描述符失败");
                }
                Toast.makeText(IDCardReaderClientHelper.getApplicationByReflect(), "[身份证读卡器]获取USB设备描述符失败", Toast.LENGTH_SHORT).show();
                return;
            }
        }

        String retStr = RootCmd.getSELinuxMode();
        int resT;

        if ("Enforcing".equals(retStr.trim())) {

            resT = NativeFunc.mt8deviceopenusb(m_device_fd, usbPermission.getUsbDevPath());
        } else {
            resT = NativeFunc.mt8deviceopen(m_device_fd);
        }
        Log.i("身份证设备名称:", usbPermission.getUsbDevPath());
        if (resT > 0) {
            if (initCallback != null) {
                initCallback.onCallback("[身份证读卡器]打开端口成功");
            }
            Log.d("身份证读卡器", "[身份证读卡器]打开端口成功" + resT);
//            Toast.makeText(IDCardReaderClientHelper.getApplicationByReflect(), "[身份证读卡器]打开端口成功" + resT, Toast.LENGTH_SHORT).show();
        } else {
            Log.d("身份证读卡器", "[身份证读卡器]打开端口失败" + resT);

            if (initCallback != null) {
                initCallback.onCallback("[身份证读卡器]打开端口失败");
            }
//            Toast.makeText(IDCardReaderClientHelper.getApplicationByReflect(), "[身份证读卡器]打开端口失败" + resT, Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 关闭设备连接
     */
    public void closeConnect() {
        if (mInitTask != null) {
            ThreadUtils.cancel(mInitTask);
            mInitTask = null;
        }
        closeIdReader();
    }

    private void unReigsterUsbPermission() {
        if (usbPermission != null) {
            usbPermission.unUsbDevPermission();
        }
    }

    public interface IReadInitCallback {
        void onCallback(String tip);
    }


}
